home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 83 / MacAddict_083_2003-07.iso / mac / Software / Development / VLC Source 0.5.3.dmg / src / video_output / video_text.c < prev    next >
C/C++ Source or Header  |  2003-04-07  |  28KB  |  609 lines

  1. /*****************************************************************************
  2.  * video_text.c : text manipulation functions
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2001 VideoLAN
  5.  * $Id: video_text.c,v 1.42 2003/01/19 03:16:24 sam Exp $
  6.  *
  7.  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  8.  *          Samuel Hocevar <sam@zoy.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  * 
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24.  
  25. /* XXX: unused */
  26. #if 0
  27. /*****************************************************************************
  28.  * Preamble
  29.  *****************************************************************************/
  30. #include <stdlib.h>                                                /* free() */
  31. #include <stdio.h>                                              /* sprintf() */
  32. #include <string.h>                                            /* strerror() */
  33.  
  34. #include <vlc/vlc.h>
  35.  
  36. #ifdef HAVE_ERRNO_H
  37. #   include <errno.h>                                               /* errno */
  38. #endif
  39.  
  40. #ifdef HAVE_FCNTL_H
  41. #   include <fcntl.h>                                              /* open() */
  42. #endif
  43.  
  44. #ifdef HAVE_UNISTD_H
  45. #   include <unistd.h>                                    /* read(), close() */
  46. #elif defined( WIN32 ) && !defined( UNDER_CE )
  47. #   include <io.h>
  48. #endif
  49.  
  50. #include "video.h"
  51. #include "video_output.h"
  52. #include "video_text.h"
  53.  
  54. /*****************************************************************************
  55.  * vout_font_t: bitmap font
  56.  *****************************************************************************
  57.  * This structure is used when the system doesn't provide a convenient function
  58.  * to print simple characters in a buffer.
  59.  * VOUT_FIXED_FONTs are stored in raw mode, character after character, with a
  60.  * first array of characters followed by a second array of borders masks.
  61.  * Therefore the border masks can't be complete if the font has pixels on the
  62.  * border.
  63.  *****************************************************************************/
  64. struct vout_font_t
  65. {
  66.     int                 i_type;                                 /* font type */
  67.     int                 i_width;                /* character width in pixels */
  68.     int                 i_height;              /* character height in pixels */
  69.     int                 i_interspacing; /* characters interspacing in pixels */
  70.     int                 i_bytes_per_line;        /* bytes per character line */
  71.     int                 i_bytes_per_char;             /* bytes per character */
  72.     u16                 i_first;                          /* first character */
  73.     u16                 i_last;                            /* last character */
  74.     byte_t *            p_data;                       /* font character data */
  75. };
  76.  
  77. /* Font types */
  78. #define VOUT_FIXED_FONT       0                         /* simple fixed font */
  79.  
  80. /*****************************************************************************
  81.  * vout_put_byte_t: PutByte function
  82.  *****************************************************************************
  83.  * These functions will transform masks in a set of pixels. For each pixel,
  84.  * character, then border and background masks are tested, and the first
  85.  * encountered color is set.
  86.  *****************************************************************************/
  87. typedef void (vout_put_byte_t)( void *p_pic, int i_byte, int i_char, int i_border,
  88.                                 int i_bg, u32 i_char_color, u32 i_border_color, u32 i_bg_color );
  89.  
  90.  
  91. /*****************************************************************************
  92.  * Macros
  93.  *****************************************************************************/
  94.  
  95. /* PUT_BYTE_MASK: put pixels from a byte-wide mask. It uses a branching tree
  96.  * to optimize the number of tests. It is used in the PutByte functions.
  97.  * This macro works for 1, 2 and 4 Bpp. */
  98. #define PUT_BYTE_MASK( i_mask, i_mask_color )                                 \
  99. if( i_mask & 0xf0 )                                       /* one from 1111 */ \
  100. {                                                                             \
  101.     if( i_mask & 0xc0 )                                   /* one from 1100 */ \
  102.     {                                                                         \
  103.         if( i_mask & 0x80 )                                        /* 1000 */ \
  104.         {                                                                     \
  105.             p_pic[0] = i_mask_color;                                          \
  106.             if( i_mask & 0x40 )                                    /* 0100 */ \
  107.             {                                                                 \
  108.                 p_pic[1] = i_mask_color;                                      \
  109.             }                                                                 \
  110.         }                                                                     \
  111.         else                                        /* not 1000 means 0100 */ \
  112.         {                                                                     \
  113.             p_pic[1] = i_mask_color;                                          \
  114.         }                                                                     \
  115.         if( i_mask & 0x30 )                               /* one from 0011 */ \
  116.         {                                                                     \
  117.             if( i_mask & 0x20 )                                    /* 0010 */ \
  118.             {                                                                 \
  119.                 p_pic[2] = i_mask_color;                                      \
  120.                 if( i_mask & 0x10 )                                /* 0001 */ \
  121.                 {                                                             \
  122.                     p_pic[3] = i_mask_color;                                  \
  123.                 }                                                             \
  124.             }                                                                 \
  125.             else                                    /* not 0010 means 0001 */ \
  126.             {                                                                 \
  127.                  p_pic[3] = i_mask_color;                                     \
  128.             }                                                                 \
  129.         }                                                                     \
  130.     }                                                                         \
  131.     else                                            /* not 1100 means 0011 */ \
  132.     {                                                                         \
  133.         if( i_mask & 0x20 )                                        /* 0010 */ \
  134.         {                                                                     \
  135.             p_pic[2] = i_mask_color;                                          \
  136.             if( i_mask & 0x10 )                                    /* 0001 */ \
  137.             {                                                                 \
  138.                 p_pic[3] = i_mask_color;                                      \
  139.             }                                                                 \
  140.         }                                                                     \
  141.         else                                        /* not 0010 means 0001 */ \
  142.         {                                                                     \
  143.             p_pic[3] = i_mask_color;                                          \
  144.         }                                                                     \
  145.     }                                                                         \
  146. }                                                                             \
  147. if( i_mask & 0x0f )                                                           \
  148. {                                                                             \
  149.     if( i_mask & 0x0c )                       /* one from 1100 */             \
  150.     {                                                                         \
  151.         if( i_mask & 0x08 )                                        /* 1000 */ \
  152.         {                                                                     \
  153.             p_pic[4] = i_mask_color;                                          \
  154.             if( i_mask & 0x04 )                                    /* 0100 */ \
  155.             {                                                                 \
  156.                 p_pic[5] = i_mask_color;                                      \
  157.             }                                                                 \
  158.         }                                                                     \
  159.         else                                        /* not 1000 means 0100 */ \
  160.         {                                                                     \
  161.             p_pic[5] = i_mask_color;                                          \
  162.         }                                                                     \
  163.         if( i_mask & 0x03 )                               /* one from 0011 */ \
  164.         {                                                                     \
  165.             if( i_mask & 0x02 )                                    /* 0010 */ \
  166.             {                                                                 \
  167.                 p_pic[6] = i_mask_color;                                      \
  168.                 if( i_mask & 0x01 )                                /* 0001 */ \
  169.                 {                                                             \
  170.                     p_pic[7] = i_mask_color;                                  \
  171.                 }                                                             \
  172.             }                                                                 \
  173.             else                                    /* not 0010 means 0001 */ \
  174.             {                                                                 \
  175.                  p_pic[7] = i_mask_color;                                     \
  176.             }                                                                 \
  177.         }                                                                     \
  178.     }                                                                         \
  179.     else                                            /* not 1100 means 0011 */ \
  180.     {                                                                         \
  181.         if( i_mask & 0x02 )                                        /* 0010 */ \
  182.         {                                                                     \
  183.             p_pic[6] = i_mask_color;                                          \
  184.             if( i_mask & 0x01 )                                    /* 0001 */ \
  185.             {                                                                 \
  186.                 p_pic[7] = i_mask_color;                                      \
  187.             }                                                                 \
  188.         }                                                                     \
  189.         else                                        /* not 0010 means 0001 */ \
  190.         {                                                                     \
  191.             p_pic[7] = i_mask_color;                                          \
  192.         }                                                                     \
  193.     }                                                                         \
  194. }
  195.  
  196. /*****************************************************************************
  197.  * Local prototypes
  198.  *****************************************************************************/
  199. static void PutByte8 ( u8 *p_pic, int i_byte, int i_char, int i_border,
  200.                        int i_bg, u32 i_char_color, u32 i_border_color,
  201.                        u32 i_bg_color );
  202. static void PutByte16( u16 *p_pic, int i_byte, int i_char, int i_border,
  203.                        int i_bg, u32 i_char_color, u32 i_border_color,
  204.                        u32 i_bg_color );
  205. static void PutByte24( void *p_pic, int i_byte, byte_t i_char, byte_t i_border,
  206.                        byte_t i_bg, u32 i_char_color, u32 i_border_color,
  207.                        u32 i_bg_color );
  208. static void PutByte32( u32 *p_pic, int i_byte, byte_t i_char, byte_t i_border,
  209.                        byte_t i_bg, u32 i_char_color, u32 i_border_color,
  210.                        u32 i_bg_color );
  211.  
  212. /*****************************************************************************
  213.  * vout_LoadFont: load a bitmap font from a file
  214.  *****************************************************************************
  215.  * This function will try to open a .psf font and load it. It will return
  216.  * NULL on error.
  217.  *****************************************************************************/
  218. vout_font_t *vout_LoadFont( vout_thread_t *p_vout, const char *psz_name )
  219. {
  220.     static char * path[] = { "share", DATA_PATH, NULL, NULL };
  221.  
  222.     char **             ppsz_path = path;
  223.     char *              psz_file;
  224. #if defined( SYS_BEOS ) || defined( SYS_DARWIN )
  225.     char *              psz_vlcpath = p_this->p_libvlc->psz_vlcpath;
  226.     int                 i_vlclen = strlen( psz_vlcpath );
  227. #endif
  228.     int                 i_char, i_line;        /* character and line indexes */
  229.     int                 i_file = -1;                          /* source file */
  230.     byte_t              pi_buffer[2];                         /* file buffer */
  231.     vout_font_t *       p_font;                           /* the font itself */
  232.  
  233.     for( ; *ppsz_path != NULL ; ppsz_path++ )
  234.     {
  235. #if defined( SYS_BEOS ) || defined( SYS_DARWIN )
  236.         /* Under BeOS, we need to add beos_GetProgramPath() to access
  237.          * files under the current directory */
  238.         if( strncmp( *ppsz_path, "/", 1 ) )
  239.         {
  240.             psz_file = malloc( strlen( psz_name ) + strlen( *ppsz_path )
  241.                                 + i_vlclen + 3 );
  242.             if( psz_file == NULL )
  243.             {
  244.                 continue;
  245.             }
  246.             sprintf( psz_file, "%s/%s/%s", psz_vlcpath, *ppsz_path, psz_name );
  247.         }
  248.         else
  249. #endif
  250.         {
  251.             psz_file = malloc( strlen( psz_name ) + strlen( *ppsz_path ) + 2 );
  252.             if( psz_file == NULL )
  253.             {
  254.                 continue;
  255.             }
  256.             sprintf( psz_file, "%s/%s", *ppsz_path, psz_name );
  257.         }
  258.  
  259.         /* Open file */
  260. #ifndef UNDER_CE /* FIXME */
  261.         i_file = open( psz_file, O_RDONLY );
  262. #endif
  263.         free( psz_file );
  264.  
  265.         if( i_file != -1 )
  266.         {
  267.             break;
  268.         }
  269.     }
  270.  
  271.     if( i_file == -1 )
  272.     {
  273. #ifdef HAVE_ERRNO_H
  274.         msg_Err( p_vout, "cannot open '%s' (%s)", psz_name, strerror(errno) );
  275. #else
  276.         msg_Err( p_vout, "cannot open '%s'", psz_name );
  277. #endif
  278.         return( NULL );
  279.     }
  280.  
  281.     /* Read magic number */
  282. #ifndef UNDER_CE /* FIXME */
  283.     if( read( i_file, pi_buffer, 2 ) != 2 )
  284.     {
  285.         msg_Err( p_vout, "unexpected end of file in '%s'", psz_name );
  286.         close( i_file );
  287.         return( NULL );
  288.     }
  289. #endif
  290.  
  291.     /* Allocate font descriptor */
  292.     p_font = malloc( sizeof( vout_font_t ) );
  293.     if( p_font == NULL )
  294.     {
  295.         msg_Err( p_vout, "out of memory" );
  296. #ifndef UNDER_CE /* FIXME */
  297.         close( i_file );
  298. #endif
  299.         return( NULL );
  300.     }
  301.  
  302.     /* Read file */
  303.     switch( ((u16)pi_buffer[0] << 8) | pi_buffer[1] )
  304.     {
  305.     case 0x3604:                                              /* .psf file */
  306.         /*
  307.          * PSF font: simple fixed font. Only the first 256 characters are read.
  308.          * Those fonts are always 1 byte wide, and 256 or 512 characters long.
  309.          */
  310.  
  311.         /* Read font header - two bytes indicate the font properties */
  312. #ifndef UNDER_CE /* FIXME */
  313.         if( read( i_file, pi_buffer, 2 ) != 2)
  314.         {
  315.             msg_Err( p_vout, "unexpected end of file in '%s'", psz_name );
  316.             free( p_font );
  317.             close( i_file );
  318.             return( NULL );
  319.         }
  320. #endif
  321.  
  322.         /* Copy font properties */
  323.         p_font->i_type =                VOUT_FIXED_FONT;
  324.         p_font->i_width =               8;
  325.         p_font->i_height =              pi_buffer[1];
  326.         p_font->i_interspacing =        8;
  327.         p_font->i_bytes_per_line =      1;
  328.         p_font->i_bytes_per_char =      pi_buffer[1];
  329.         p_font->i_first =               0;
  330.         p_font->i_last =                255;
  331.  
  332.         /* Allocate font space */
  333.         p_font->p_data = malloc( 2 * 256 * pi_buffer[1] );
  334.         if( p_font->p_data == NULL )
  335.         {
  336.             msg_Err( p_vout, "out of memory" );
  337.             free( p_font );
  338. #ifndef UNDER_CE /* FIXME */
  339.             close( i_file );
  340. #endif
  341.             return( NULL );
  342.         }
  343.  
  344.         /* Copy raw data */
  345. #ifndef UNDER_CE /* FIXME */
  346.         if( read( i_file, p_font->p_data, 256 * pi_buffer[1] ) != 256 * pi_buffer[1] )
  347.         {
  348.             msg_Err( p_vout, "unexpected end of file in '%s'", psz_name );
  349.             free( p_font->p_data );
  350.             free( p_font );
  351.             close( i_file );
  352.             return( NULL );
  353.         }
  354. #endif
  355.  
  356.         /* Compute border masks - remember that masks have the same matrix as
  357.          * characters, so an empty character border is required to have a
  358.          * complete border mask. */
  359.         for( i_char = 0; i_char <= 255; i_char++ )
  360.         {
  361.             for( i_line = 0; i_line < pi_buffer[1]; i_line++ )
  362.             {
  363.  
  364.                 p_font->p_data[ (i_char + 256) * pi_buffer[1] + i_line ] =
  365.                     ((p_font->p_data[ i_char * pi_buffer[1] + i_line ] << 1) |
  366.                      (p_font->p_data[ i_char * pi_buffer[1] + i_line ] >> 1) |
  367.                      (i_line > 0 ? p_font->p_data[ i_char * pi_buffer[1] + i_line - 1]: 0) |
  368.                      (i_line < pi_buffer[1] - 1 ? p_font->p_data[ i_char * pi_buffer[1] + i_line + 1]: 0))
  369.                     & ~p_font->p_data[ i_char * pi_buffer[1] + i_line ];
  370.             }
  371.         }
  372.  
  373.         break;
  374.     default:
  375.         msg_Err( p_vout, "file '%s' has an unknown format", psz_name );
  376.         free( p_font );
  377. #ifndef UNDER_CE /* FIXME */
  378.         close( i_file );
  379. #endif
  380.         return( NULL );
  381.         break;
  382.     }
  383.  
  384.     msg_Err( p_vout, "loaded %s, type %d, %d-%dx%d", psz_name, p_font->i_type,
  385.              p_font->i_width, p_font->i_interspacing, p_font->i_height );
  386.  
  387.     return( p_font );
  388. }
  389.  
  390. /*****************************************************************************
  391.  * vout_UnloadFont: unload a font
  392.  *****************************************************************************
  393.  * This function free the resources allocated by vout_LoadFont
  394.  *****************************************************************************/
  395. void vout_UnloadFont( vout_font_t *p_font )
  396. {
  397.     /* If no font was loaded, do nothing */
  398.     if( p_font == NULL )
  399.     {
  400.         return;
  401.     }
  402.  
  403.     free( p_font->p_data );
  404.     free( p_font );
  405. }
  406.  
  407. /*****************************************************************************
  408.  * vout_TextSize: return the dimensions of a text
  409.  *****************************************************************************
  410.  * This function is used to align text. It returns the width and height of a
  411.  * given text.
  412.  *****************************************************************************/
  413. void vout_TextSize( vout_font_t *p_font, int i_style, const char *psz_text, int *pi_width, int *pi_height )
  414. {
  415.     /* If no font was loaded, do nothing */
  416.     if( p_font == NULL )
  417.     {
  418.         *pi_width = *pi_height = 0;
  419.         return;
  420.     }
  421.  
  422.     switch( p_font->i_type )
  423.     {
  424.     case VOUT_FIXED_FONT:
  425.         *pi_width  = ((i_style & WIDE_TEXT) ? p_font->i_interspacing * 2 : p_font->i_interspacing) *
  426.             (strlen( psz_text ) - 1) + p_font->i_width;
  427.         *pi_height = p_font->i_height;
  428.         if( i_style & ITALIC_TEXT )
  429.         {
  430.             *pi_width = *pi_height / 3;
  431.         }
  432.         break;
  433.     }
  434. }
  435.  
  436. /*****************************************************************************
  437.  * vout_Print: low level printing function
  438.  *****************************************************************************
  439.  * This function prints a text, without clipping, in a buffer using a
  440.  * previously loaded bitmap font.
  441.  *****************************************************************************/
  442. void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int i_bytes_per_line,
  443.                  u32 i_char_color, u32 i_border_color, u32 i_bg_color, int i_style, const char *psz_text, int i_percent)
  444. {
  445.     byte_t       *p_char, *p_border;       /* character and border mask data */
  446.     int          i_char_mask, i_border_mask, i_bg_mask;             /* masks */
  447.     int          i_line;                        /* current line in character */
  448.     int          i_byte;                        /* current byte in character */
  449.     int          i_interspacing;                 /* offset between two chars */
  450.     int          i_font_bytes_per_line, i_font_height;    /* font properties */
  451.     unsigned int i_position, i_end;                     /* current position  */
  452.     vout_put_byte_t *p_PutByte;                          /* PutByte function */
  453.  
  454.     /* If no font was loaded, do nothing */
  455.     if( p_font == NULL )
  456.     {
  457.         return;
  458.     }
  459.  
  460.     /* FIXME: background: can be something else that whole byte ?? */
  461.  
  462.     /* Select output function */
  463.     switch( i_bytes_per_pixel )
  464.     {
  465.     case 1:
  466.         p_PutByte = (vout_put_byte_t *) PutByte8;
  467.         break;
  468.     case 2:
  469.         p_PutByte = (vout_put_byte_t *) PutByte16;
  470.         break;
  471.     case 3:
  472.         p_PutByte = (vout_put_byte_t *) PutByte24;
  473.         break;
  474.     case 4:
  475.     default:
  476.         p_PutByte = (vout_put_byte_t *) PutByte32;
  477.         break;
  478.     }
  479.  
  480.     /* Choose masks and copy font data to local variables */
  481.     i_char_mask =               (i_style & VOID_TEXT) ?         0 : 0xff;
  482.     i_border_mask =             (i_style & OUTLINED_TEXT) ?     0xff : 0;
  483.     i_bg_mask =                 (i_style & OPAQUE_TEXT) ?       0xff : 0;
  484.  
  485.     i_font_bytes_per_line =     p_font->i_bytes_per_line;
  486.     i_font_height =             p_font->i_height;
  487.     i_interspacing =            i_bytes_per_pixel * ((i_style & WIDE_TEXT) ?
  488.                                                      p_font->i_interspacing * 2 :
  489.                                                      p_font->i_interspacing);
  490.  
  491.     /* compute where to stop... */
  492.     i_end = (int) (i_percent * strlen(psz_text) / (s64)100);
  493.     if(i_end > strlen(psz_text))
  494.         i_end = strlen(psz_text);
  495.     
  496.     
  497.     /* Print text */
  498.     for( i_position = 0; i_position < i_end; i_position++ ,psz_text++ )
  499.     {
  500.         /* Check that the character is valid */
  501.         if( (*psz_text >= p_font->i_first) && (*psz_text <= p_font->i_last) )
  502.         {
  503.             /* Select character - bytes per char is always valid, event for
  504.              * non fixed fonts */
  505.             p_char =    p_font->p_data + (*psz_text - p_font->i_first) * p_font->i_bytes_per_char;
  506.             p_border =  p_char + (p_font->i_last - p_font->i_first + 1) * p_font->i_bytes_per_char;
  507.  
  508.             /* Select base address for output */
  509.             switch( p_font->i_type )
  510.             {
  511.             case VOUT_FIXED_FONT:
  512.                 /*
  513.                  * Simple fixed width font
  514.                  */
  515.  
  516.                 /* Italic text: shift picture start right */
  517.                 if( i_style & ITALIC_TEXT )
  518.                 {
  519.                     p_pic += i_bytes_per_pixel * (p_font->i_height / 3);
  520.                 }
  521.  
  522.                 /* Print character */
  523.                 for( i_line = 0; i_line < i_font_height; i_line ++ )
  524.                 {
  525.                     for( i_byte = 0; i_byte < i_font_bytes_per_line; i_byte++, p_char++, p_border++)
  526.                     {
  527.                         /* Put pixels */
  528.                         p_PutByte( p_pic + i_bytes_per_line * i_line, i_byte,
  529.                                    *p_char & i_char_mask, *p_border & i_border_mask, i_bg_mask,
  530.                                    i_char_color, i_border_color, i_bg_color );
  531.                     }
  532.  
  533.                     /* Italic text: shift picture start left */
  534.                     if( (i_style & ITALIC_TEXT) && !(i_line % 3) )
  535.                     {
  536.                         p_pic -= i_bytes_per_pixel;
  537.                     }
  538.                 }
  539.  
  540.                 /* Jump to next character */
  541.                 p_pic += i_interspacing;
  542.                 break;
  543.             }
  544.         }
  545.     }
  546. }
  547.  
  548. /* following functions are local */
  549.  
  550. /*****************************************************************************
  551.  * PutByte8: print a fixed width font character byte in 1 Bpp
  552.  *****************************************************************************/
  553. static void PutByte8( u8 *p_pic, int i_byte, int i_char, int i_border,
  554.                        int i_bg, u32 i_char_color, u32 i_border_color,
  555.                        u32 i_bg_color )
  556. {
  557.     /* Computes position offset and background mask */
  558.     p_pic += 8 * i_byte;
  559.     i_bg &= ~(i_char | i_border);
  560.  
  561.     /* Put character bits */
  562.     PUT_BYTE_MASK(i_char, i_char_color);
  563.     PUT_BYTE_MASK(i_border, i_border_color);
  564.     PUT_BYTE_MASK(i_bg, i_bg_color);
  565. }
  566.  
  567. /*****************************************************************************
  568.  * PutByte16: print a fixed width font character byte in 2 Bpp
  569.  *****************************************************************************/
  570. static void PutByte16( u16 *p_pic, int i_byte, int i_char, int i_border,
  571.                        int i_bg, u32 i_char_color, u32 i_border_color,
  572.                        u32 i_bg_color )
  573. {
  574.     /* Computes position offset and background mask */
  575.     p_pic += 8 * i_byte;
  576.     i_bg &= ~(i_char | i_border);
  577.  
  578.     /* Put character bits */
  579.     PUT_BYTE_MASK(i_char, i_char_color);
  580.     PUT_BYTE_MASK(i_border, i_border_color);
  581.     PUT_BYTE_MASK(i_bg, i_bg_color);
  582. }
  583.  
  584. /*****************************************************************************
  585.  * PutByte24: print a fixed width font character byte in 3 Bpp
  586.  *****************************************************************************/
  587. static void PutByte24( void *p_pic, int i_byte, byte_t i_char, byte_t i_border, byte_t i_bg,
  588.                        u32 i_char_color, u32 i_border_color, u32 i_bg_color )
  589. {
  590.     /* XXX?? */
  591. }
  592.  
  593. /*****************************************************************************
  594.  * PutByte32: print a fixed width font character byte in 4 Bpp
  595.  *****************************************************************************/
  596. static void PutByte32( u32 *p_pic, int i_byte, byte_t i_char, byte_t i_border, byte_t i_bg,
  597.                        u32 i_char_color, u32 i_border_color, u32 i_bg_color )
  598. {
  599.     /* Computes position offset and background mask */
  600.     p_pic += 8 * i_byte;
  601.     i_bg &= ~(i_char | i_border);
  602.  
  603.     /* Put character bits */
  604.     PUT_BYTE_MASK(i_char, i_char_color);
  605.     PUT_BYTE_MASK(i_border, i_border_color);
  606.     PUT_BYTE_MASK(i_bg, i_bg_color);
  607. }
  608. #endif
  609.